# Lucid is (C) Copyright 2006-2007 by Infiscape Corporation
#
# This file is part of Lucid, a PyOpenSG example application.
#
# Lucid is free software; you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version.
#
# Lucid is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program.  If not, see <http://www.gnu.org/licenses/>.

from PyQt4 import QtGui, QtCore
import transform_editor_base2
import lucid.core
import osg2
from pydispatch import dispatcher

class TransformCoreEditorPlugin(lucid.core.IFcEditorPlugin):
   """ Viewer that displays a node editor panel.  """
   def __init__(self):
      super(TransformCoreEditorPlugin, self).__init__()
      self.core = None
      self.editor_widget = TransformEditorWidget(self)

   @staticmethod
   def getName():
      return "Transform Core Editor"
      
   @staticmethod
   def getSupportedFcTypes():
      """ Return the type(s) that we support editing. """
      return [osg2.Transform, ]
   
   def getEditorWidget(self):
      return self.editor_widget

   def setFieldContainer(self, fc):
      assert type(fc) == osg2.Transform      
      self.core = fc
      self.editor_widget.updateView()      

class TransformEditorWidget(QtGui.QWidget, transform_editor_base2.Ui_TransformEditorBase2):
   """ Simple container widget. """
   def __init__(self, plugin, parent=None):
      QtGui.QWidget.__init__(self, parent)
      self.plugin = plugin      
      self.setupUi(self)
      self.updateView()

   def setupUi(self, Form):
      transform_editor_base2.Ui_TransformEditorBase2.setupUi(self,Form)
      
      # Custom setup

      # Set up translation connections.
      self.connect(self.mXTranslationWheel, QtCore.SIGNAL("valueChanged(double)"), self.onWheelChanged)
      self.connect(self.mYTranslationWheel, QtCore.SIGNAL("valueChanged(double)"), self.onWheelChanged)
      self.connect(self.mZTranslationWheel, QtCore.SIGNAL("valueChanged(double)"), self.onWheelChanged)

      self.connect(self.mXRotationWheel, QtCore.SIGNAL("valueChanged(double)"), self.onWheelChanged)
      self.connect(self.mYRotationWheel, QtCore.SIGNAL("valueChanged(double)"), self.onWheelChanged)
      self.connect(self.mZRotationWheel, QtCore.SIGNAL("valueChanged(double)"), self.onWheelChanged)
      
      self.connect(self.mXScaleWheel, QtCore.SIGNAL("valueChanged(double)"), self.onWheelChanged)
      self.connect(self.mYScaleWheel, QtCore.SIGNAL("valueChanged(double)"), self.onWheelChanged)
      self.connect(self.mZScaleWheel, QtCore.SIGNAL("valueChanged(double)"), self.onWheelChanged)

      self.connect(self.mXTranslation, QtCore.SIGNAL("editingFinished()"), self.onXformRotEdit)
      self.connect(self.mYTranslation, QtCore.SIGNAL("editingFinished()"), self.onXformRotEdit)
      self.connect(self.mZTranslation, QtCore.SIGNAL("editingFinished()"), self.onXformRotEdit)
      self.connect(self.mXRotation, QtCore.SIGNAL("editingFinished()"), self.onXformRotEdit)
      self.connect(self.mYRotation, QtCore.SIGNAL("editingFinished()"), self.onXformRotEdit)
      self.connect(self.mZRotation, QtCore.SIGNAL("editingFinished()"), self.onXformRotEdit)
      self.connect(self.mXScale, QtCore.SIGNAL("editingFinished()"), self.onXformRotEdit)
      self.connect(self.mYScale, QtCore.SIGNAL("editingFinished()"), self.onXformRotEdit)
      self.connect(self.mZScale, QtCore.SIGNAL("editingFinished()"), self.onXformRotEdit)
      
      self.connect(self.mQuatAxisX,   QtCore.SIGNAL("valueChanged(double)"), self.onXformRotEdit)
      self.connect(self.mQuatAxisY,   QtCore.SIGNAL("valueChanged(double)"), self.onXformRotEdit)
      self.connect(self.mQuatAxisZ,   QtCore.SIGNAL("valueChanged(double)"), self.onXformRotEdit)
      self.connect(self.mQuatDegrees, QtCore.SIGNAL("valueChanged(double)"), self.onXformRotEdit)
   
   def onWheelChanged(self, val):
      print "Changed: ", val
      self.mXTranslation.setValue(self.mXTranslationWheel.value())
      self.mYTranslation.setValue(self.mYTranslationWheel.value())
      self.mZTranslation.setValue(self.mZTranslationWheel.value())
      self.mXRotation.setValue(self.mXRotationWheel.value())
      self.mYRotation.setValue(self.mYRotationWheel.value())
      self.mZRotation.setValue(self.mZRotationWheel.value())
      self.mXScale.setValue(self.mXScaleWheel.value())
      self.mYScale.setValue(self.mYScaleWheel.value())
      self.mZScale.setValue(self.mZScaleWheel.value())
      self.onXformRotEdit()
      

   def onXformRotEdit(self):      
      print "Xform rot edit called"
      print "(%s, %s, %s) (%s, %s, %s)" % (self.mXTranslation.value(),
                                           self.mYTranslation.value(),
                                           self.mZTranslation.value(),
                                           self.mXRotation.value(),
                                           self.mYRotation.value(),
                                           self.mZRotation.value())
      rot = [self.mXRotation.value(), self.mYRotation.value(), self.mZRotation.value()]      
      quat_rot = [self.mQuatAxisX.value(), self.mQuatAxisY.value(), self.mQuatAxisZ.value(), self.mQuatDegrees.value()]
      
      #rot = [gmtl.Math.deg2Rad(i) for i in rot]
      trans = osg2.Vec3f(self.mXTranslation.value(), 
                         self.mYTranslation.value(), 
                         self.mZTranslation.value())
      scale = osg2.Vec3f(self.mXScale.value(), 
                         self.mYScale.value(), 
                         self.mZScale.value())
      rot_q = osg2.Quaternion()
      rot_q.setValueAsAxisDeg(*quat_rot)
      
      new_matrix = osg2.Matrix()
      new_matrix.setTransform(trans,rot_q, scale)
      core = self.plugin.core
      if core:
         core.setMatrix(new_matrix)


   def updateView(self):
      core = self.plugin.core      
      if core:
         cur_mat = core.getMatrix()
         
         (trans, rot, scale, scaleOr) = cur_mat.getTransform()
         #(trans, rot, scale, scaleOr) = (osg2.Vec3f(), 
         #                                osg2.Quaternion(),
         #                                osg2.Vec3f(),
         #                                osg2.Quaternion())
         
         (quat_axis, quat_deg) = rot.getValueAsAxisDeg()
         
         wheels = [self.mXTranslationWheel, self.mYTranslationWheel, self.mZTranslationWheel,
                    self.mXRotationWheel, self.mYRotationWheel, self.mZRotationWheel,
                    self.mXScaleWheel, self.mYScaleWheel, self.mZScaleWheel]
         for w in wheels:
            w.setTracking(False)
         for w in [self.mQuatAxisX, self.mQuatAxisY, self.mQuatAxisZ, self.mQuatDegrees]:
            w.blockSignals(True)
   
         self.mXTranslation.setValue(trans[0])
         self.mXTranslationWheel.setValue(trans[0])
         self.mYTranslation.setValue(trans[1])
         self.mYTranslationWheel.setValue(trans[1])
         self.mZTranslation.setValue(trans[2])
         self.mZTranslationWheel.setValue(trans[2])
   
         #self.mXRotation.setValue(rot[0])
         #self.mXRotationWheel.setValue(rot[0])
         #self.mYRotation.setValue(rot[1])
         #self.mYRotationWheel.setValue(rot[1])
         #self.mZRotation.setValue(rot[2])
         #self.mZRotationWheel.setValue(rot[2])
         
         self.mQuatAxisX.setValue(quat_axis[0])
         self.mQuatAxisY.setValue(quat_axis[1])
         self.mQuatAxisZ.setValue(quat_axis[2])
         self.mQuatDegrees.setValue(quat_deg)
   
         self.mXScale.setValue(scale[0])
         self.mXScaleWheel.setValue(scale[0])
         self.mYScale.setValue(scale[1])
         self.mYScaleWheel.setValue(scale[1])
         self.mZScale.setValue(scale[2])
         self.mZScaleWheel.setValue(scale[2])
   
         #self.mMatrixModel = MatrixModel(cur_mat, self)
         #self.mMatrixView.setModel(self.mMatrixModel)
         
         for w in wheels:
            w.setTracking(True)
         for w in [self.mQuatAxisX, self.mQuatAxisY, self.mQuatAxisZ, self.mQuatDegrees]:
            w.blockSignals(False)
   
